/*
 * Copyright (c)  2015~2020, xforceplus
 * All rights reserved.
 * Project:datacare-orm
 * Id: AbstractUpsertSqlManager.java   2020-10-12 12-59-14
 * Author: Evan
 */
package cn.datacare.orm.manager.impl;

import cn.datacare.orm.database.ClassDesc;
import cn.datacare.orm.exception.OrmCoreException;
import cn.datacare.orm.manager.UpsertSqlManager;
import cn.datacare.orm.util.kit.BeanKit;

import java.util.List;

import static cn.datacare.orm.exception.OrmErrorCode.ID_EXPECTED_ONE_ERROR;

/**
 * <p>
 * Title:
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: 2015~2020
 * </p>
 * <p>
 * Company/Department: xforceplus
 * </p>
 *
 * @author Evan
 * <b>Creation Time:</b> 2020-10-12 12-59-14
 * @since V1.0
 */
public abstract class AbstractUpsertSqlManager  extends AbstractUpdateSqlManager implements UpsertSqlManager {

    /**
     * 先判断是否主键为空，如果为空，则插入，如果不为空，则从数据库
     * 出一条，如果未取到，则插入一条，其他情况按照主键更新
     *
     * @param obj
     * @return 受影响条数
     */
    @Override
    public int upsert(Object obj) {
        return  this.upsert(obj,false);
    }

    /**
     * 先判断是否主键为空，如果为空，则插入，如果不为空，则从数据库
     * 取出一条，如果未取到，则插入一条，其他情况按照主键更新
     *
     * @param obj
     * @return 受影响条数
     */
    @Override
    public int upsertByTemplate(Object obj) {
        return  this.upsert(obj,true);
    }

    /**
     * 先判断是否主键为空，如果为空，则插入，如果不为空，则从数据库
     * 取出一条，如果未取到，则插入一条，其他情况按照主键更新
     *
     * @param obj      待更新/插入的实体对象
     * @param template
     * @return 受影响条数
     */
    @Override
    public int upsert(Object obj, boolean template) {
        Class clazz = obj.getClass();
        ClassDesc classDesc =this.getClassDesc(clazz);
        List<String> idProperties = classDesc.getIdAttrs();
        if(idProperties.size()!=1){
            throw new OrmCoreException(ID_EXPECTED_ONE_ERROR);

        }
        Object pk = BeanKit.getBeanProperty(obj,idProperties.get(0));
        if(pk==null){
            //插入
            return template?this.insertTemplate(obj,true):this.insert(obj,true);
        }
        Object dbValue = this.single(clazz,pk);
        if(dbValue==null){
            //还是插入
            return template?this.insertTemplate(obj,true):this.insert(obj,true);
        }

        //更新
        return template?this.updateTemplateById(obj):this.updateById(obj);
    }
}
